/** 内置工具类型
 * Record 将右侧的属性，定义为某种类型 Record<UserProps, string>
 * Readonly 将所有字段，变成不可修改
 * Partial 将所有字段，变成可选
 * Pick 选中当中某些字段 Pick<User,'name'|'age'>
 * Omit 排除当中某些字段 Omit<User,'name'|'age'>
 * Exclude 差集
 * Extract 交集
 * Parameters 返回函数的参数类型
 * ReturnType 返回函数的结果类型
 * Awaited 来获取异步的类型
 * NonNullable 用于从给定的类型中移除 null 和 undefined。它返回一个新的类型，该类型是原始类型去除了 null 和 undefined 后的结果。
 */
type UserProps = 'name' | 'job' | 'email';
// 等价于你一个个实现这些属性了，通UserType
type User = Record<UserProps, string>;
type UserType = {
  name: string
  job: string
  email: string
};
const user: User = {
  name: 'admin',
  job: 'admin',
  email: '110@qq.com'
};

type ReadonlyUser = Readonly<User>;
const readonlyUser: ReadonlyUser = {
  name: 'John Doe',
  job: 'admin',
  email: '110@qq.com'
};
// 修改 readonlyUser 对象的属性
// readonlyUser.name = 'Jane Doe';  // 报错
// readonlyUser.job = '123';  // 报错
// readonlyUser.email = 'jane.doe@example.com';  // 报错


// Partial使定义的属性变为可选
type PartialUser = Partial<User>;

// 可以不实现全部的属性了！
const partialUser: PartialUser = {
  name: 'John Doe',
  job: 'admin'
};

type RequiredUser = Required<PartialUser>;
// 现在你必须全部实现这些属性了
const requiredUser: RequiredUser = {
  name: 'admin',
  job: 'admin',
  email: '110@qq.com'
};

// 将age设置为可选
type UserWithOptionalAge = Omit<User, 'job'> & { job?: string }
const userWithOptionalAge:UserWithOptionalAge = {
  name:'admin',
  email: '110@qq.com'
}
/** 差集、交集*/
type UserProps1 = 'name' | 'age' | 'email' | 'phone' | 'address';
type RequiredUserProps1 = 'name' | 'email';
// OptionalUserProps = UserProps1 - RequiredUserProps1 = "age" | "phone" | "address"
type OptionalUserProps = Exclude<UserProps1, RequiredUserProps1>;
const optionalUserProps: OptionalUserProps = 'age';

// RequiredUserPropsOnly = UserProps1 ∩ RequiredUserProps1 = "name" | "email"
type RequiredUserPropsOnly = Extract<UserProps1, RequiredUserProps1>;
const requiredUserPropsOnly: RequiredUserPropsOnly = 'name';


// 内置工具类型中提供了 Parameters 和 ReturnType 这两个类型来提取函数的参数类型与返回值类型
type Add = (x: number, y: number) => number;

type AddParams = Parameters<Add>; // [number, number] 类型
type AddResult = ReturnType<Add>; // number 类型

const addParams: AddParams = [1, 2];
const addResult: AddResult = 3;


const addHandler = (x: number, y: number) => x + y;

type Add1 = typeof addHandler; // (x: number, y: number) => number;

type AddParams1 = Parameters<Add1>; // [number, number] 类型
type AddResult1 = ReturnType<Add1>; // number 类型

const addParams1: AddParams1 = [1, 2];
const addResult1: AddResult1 = 3;

// 定义一个函数，该函数返回一个 Promise 对象
async function getPromise() {
  return new Promise<string>((resolve) => {
    setTimeout(() => {
      resolve("Hello, World!");
    }, 1000);
  });
}
// Awaited 来获取异步的类型
type Result = Awaited<ReturnType<typeof getPromise>>; // string 类型


// 声明一个可能为null或undefined的变量
let foo: string | null | undefined = 'Hello';
// 使用 NonNullable 排除 null 和 undefined
let bar: NonNullable<typeof foo> = foo; // bar 的类型为 string


